home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / Talking Telnet / source / ae / ae.c next >
Text File  |  1996-06-22  |  8KB  |  309 lines

  1. /*
  2. *    ae.c
  3. *    Code to handle the AppleEvents we recognize
  4. *****************************************************************
  5. *    NCSA Telnet for the Macintosh                                *
  6. *                                                                *
  7. *    National Center for Supercomputing Applications                *
  8. *    Software Development Group                                    *
  9. *    152 Computing Applications Building                            *
  10. *    605 E. Springfield Ave.                                        *
  11. *    Champaign, IL  61820                                        *
  12. *                                                                *
  13. *    Copyright (c) 1986-1994,                                    *
  14. *    Board of Trustees of the University of Illinois                *
  15. ****************************************************************/
  16.  
  17.  
  18. #include "wind.h"                // For connections.proto.h
  19. #include "ae.proto.h"
  20. #include "connections.proto.h"    // For OpenConnectionFromURL proto
  21. #include "Sets.proto.h"            // For readconfig proto
  22. #include "macros.proto.h"        // For loadMacro proto
  23. #include "menuseg.proto.h"        // For HandleQuit proto
  24. #include "debug.h"                // For ShowDebugWindow proto
  25.  
  26.  
  27. static void ProcessURLEscapeCodes (char *url, char **end);
  28.  
  29. void AEunload(void) { }
  30.  
  31. SIMPLE_UPP(MyHandleODoc, AEEventHandler);
  32. pascal OSErr  MyHandleODoc (AppleEvent *theAppleEvent, AppleEvent* reply, long
  33.                                                         handlerRefCon)
  34. {
  35.     FSSpec        myFSS;
  36.     AEDescList    docList;
  37.     OSErr        err;
  38.     long        index, itemsInList;
  39.     Size        actualSize;
  40.     AEKeyword    keywd;
  41.     DescType    returnedType;
  42.     FInfo        fileInfo;
  43.     
  44.     if ((err = AEGetParamDesc (theAppleEvent, keyDirectObject, typeAEList, &docList)) != noErr)
  45.         return err;
  46.  
  47.     // check for missing parameters
  48.     if ((err = MyGotRequiredParams (theAppleEvent)) != noErr)
  49.         return err;
  50.  
  51.     // count the number of descriptor records in the list
  52.     if ((err = AECountItems (&docList, &itemsInList)) != noErr)
  53.         return err;
  54.  
  55.     for (index = 1; index <= itemsInList; index++) {
  56.             err = AEGetNthPtr (&docList, index, typeFSS, &keywd, &returnedType, 
  57.                                 (Ptr) &myFSS, sizeof(myFSS), &actualSize);
  58.             if (err) return err;
  59.             
  60.             FSpGetFInfo(&myFSS, &fileInfo);        /* make sure it's a data file */
  61.             if (fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == kNCSASetFileType)
  62.                 readconfig(myFSS);        // Read the actual set
  63.             else if(fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == 'TEXT')
  64.                 loadMacros(&myFSS);
  65.             else if (fileInfo.fdCreator == kNCSACreatorSignature && fileInfo.fdType == 'DBUG')
  66.             {
  67.                 TelInfo->debug = TRUE;
  68.                 ShowDebugWindow();    
  69.             }        
  70.     }                
  71.  
  72.     err = AEDisposeDesc (&docList);
  73.     return noErr;
  74. }
  75.  
  76. SIMPLE_UPP(MyHandlePDoc, AEEventHandler);
  77. pascal OSErr  MyHandlePDoc (AppleEvent *theAppleEvent, AppleEvent *reply, long
  78.                                                         handlerRefCon)
  79. {
  80.     // We don't print files.
  81.     return (errAEEventNotHandled);
  82. }
  83.  
  84. SIMPLE_UPP(MyHandleOApp, AEEventHandler);
  85. pascal OSErr  MyHandleOApp (AppleEvent *theAppleEvent, AppleEvent *reply, long
  86.                                                         handlerRefCon)
  87. {
  88.     // Don't need to do anything for OApp.
  89.     return noErr;
  90. }
  91.  
  92. SIMPLE_UPP(MyHandleQuit, AEEventHandler);
  93. pascal OSErr  MyHandleQuit (AppleEvent *theAppleEvent, AppleEvent *reply, long
  94.                                                         handlerRefCon)
  95. {
  96.     if (HandleQuit())
  97.         return(-128);    // userCancelledErr
  98.             
  99.     return(noErr);    
  100. }
  101.  
  102. SIMPLE_UPP(MyHandleGURL, AEEventHandler);
  103. pascal OSErr  MyHandleGURL (AppleEvent *theAppleEvent, AppleEvent* reply, long
  104.                                                         handlerRefCon)
  105. {
  106.     OSErr        err;
  107.     DescType    returnedType;
  108.     Size        actualSize;
  109.     char        URLString[255];
  110.     char        *beg, *end, *user, *password, *portstring, *host;
  111.  
  112.     if ((err = AEGetParamPtr(theAppleEvent, keyDirectObject, typeChar, &returnedType,
  113.                                 URLString, sizeof(URLString)-1, &actualSize)) != noErr)
  114.         return err;
  115.  
  116.     // check for missing parameters
  117.     if ((err = MyGotRequiredParams(theAppleEvent)) != noErr)
  118.         return err;
  119.  
  120.     URLString[actualSize] = 0;        // Terminate the C string
  121.     beg = &URLString[0];
  122.     end = &URLString[actualSize-1];
  123.  
  124.     // Strip leading spaces
  125.     while ((beg < end) && (*beg == ' '))
  126.         beg++;
  127.  
  128.     // Strip trailing spaces
  129.     while ((end < beg) && (*end == ' '))
  130.         end--;
  131.  
  132.     // Look for (and strip) beginning and ending angle brackets
  133.     if (*beg == '<') {
  134.         if (*end != '>') {    // Leading angle bracket, but no trailing angle bracket
  135.             err = paramErr;
  136.             goto badExit;
  137.             }
  138.         
  139.         // Nuke the brackets
  140.         beg++;
  141.         end--;
  142.         }
  143.  
  144.     // Terminate the string we currently have (for strncmp fn's)
  145.     *(end+1) = 0;
  146.  
  147.     // Look for (and strip) leading "URL:"
  148.     if (!strncmp(beg, "URL:", 4)) {
  149.         beg += 4;
  150.         }
  151.  
  152.     // Look for (and strip) leading "telnet://"
  153.     if (strncmp(beg, "telnet://", 9))   // No leading "telnet://"
  154.     {
  155.         if (strncmp(beg, "rlogin://", 9))
  156.         {    
  157.         err = paramErr;                    
  158.             goto badExit;
  159.         }
  160.     }
  161.     beg += 9;
  162.  
  163.     // Drop any ending slash
  164.     if (*end == '/') {
  165.         *end = 0;
  166.         end--;
  167.         }
  168.  
  169.     // Process any escaped characters
  170.     ProcessURLEscapeCodes(beg, &end);
  171.  
  172.     // Set up for URL parsing
  173.     password = nil;
  174.     portstring = nil;
  175.     host = nil;
  176.  
  177.     // Assume <user> exists
  178.     user = beg;
  179.     
  180.     // Leading : or @ is a no-no
  181.     if ((*beg == ':') || (*beg == '@')) {
  182.         err = paramErr;
  183.         goto badExit;
  184.         }
  185.  
  186.     // Scan for : or @ or end of string
  187.     while ((beg <= end) && (*beg != ':') && (*beg != '@'))
  188.         beg++;
  189.  
  190.     // If we reached the end, only a host was given
  191.     if (beg > end) {
  192.         host = user;
  193.         user = nil;
  194.         goto goodUrl;
  195.         }
  196.  
  197.     // If : was found, scan in the password (or port)
  198.     if (*beg == ':') {
  199.         *beg++ = 0;
  200.         password = beg;
  201.  
  202.         // Scan for : or @ or end of string
  203.         while ((beg <= end) && (*beg != ':') && (*beg != '@'))
  204.             beg++;
  205.  
  206.         if (*beg == ':') {    // xxxx:yyyy:<anything> is a no-no
  207.             err = paramErr;
  208.             goto badExit;
  209.             }
  210.  
  211.         if (*beg != '@') {    // End of string.  Must be host:port
  212.             host = user;
  213.             user = nil;
  214.             portstring = password;
  215.             password = nil;
  216.             goto goodUrl;
  217.             }
  218.  
  219.         // Have xxx:yyy@<something>
  220.         *beg++ = 0;    // Terminate password string
  221.         }        
  222.     else {        // Found @
  223.         *beg++ = 0;    // Terminate user string
  224.         }
  225.         
  226.     // Ok at this point have xxx:yyy@<something> or xxxx@<something>
  227.     host = beg;
  228.  
  229.     // Scan for : or @ or end of string
  230.     while ((beg <= end) && (*beg != ':') && (*beg != '@') && (*beg != '/')) //CCP fix bad telnets
  231.         beg++;
  232.  
  233.     if (*beg == '@') { //xxx[:yyyy]@xxx@ is a no-no
  234.         err = paramErr;
  235.         goto badExit;
  236.         }
  237.  
  238.     if (*beg != ':') { // End of string, we have xxxx[:yyyy]@zzzz
  239.         *beg = 0;
  240.         }
  241.     else {
  242.         *beg++ = 0;    // Terminate host string
  243.         portstring = beg;
  244.         }
  245.  
  246. goodUrl:
  247.     OpenConnectionFromURL(host, portstring, user, password);
  248.     err = noErr;
  249.  
  250. badExit:
  251.     return err;    
  252. }
  253.  
  254. /*----------------------------------------------------------------------------
  255.     ProcessURLEscapeCodes
  256.     
  257.     Process "%xx" escape codes in a URL string (replace them by the characters
  258.     they represent).
  259.     
  260.     Entry:    url = URL with escape codes.
  261.             
  262.     Exit:    url = URL with escape codes replaced by the characters they
  263.                 represent.
  264.  
  265.     Copyright © 1994, Northwestern University.
  266.     Modified 12/94 Jim Browne for NCSA
  267. ----------------------------------------------------------------------------*/
  268.  
  269. static void ProcessURLEscapeCodes (char *url, char **end)
  270. {
  271.     char *p, *q;
  272.     char c1, c2;
  273.     p = q = url;
  274.     while (*p != 0) {
  275.         if (*p == '%') {
  276.             c1 = tolower(*(p+1));
  277.             c2 = tolower(*(p+2));
  278.             if (isxdigit(c1) && isxdigit(c2)) {
  279.                 c1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
  280.                 c2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
  281.                 *q++ = (c1 << 4) + c2;
  282.                 p += 3;
  283.             } else {
  284.                 *q++ = *p++;
  285.             }
  286.         } else {
  287.             *q++ = *p++;
  288.         }
  289.     }
  290.     *q = 0;
  291.     *end = q-1;
  292. }
  293.  
  294. OSErr MyGotRequiredParams (AppleEvent *theAppleEvent)
  295. {
  296.     DescType    returnedType;
  297.     Size        actualSize;
  298.     OSErr        err;
  299.  
  300.     err = AEGetAttributePtr (theAppleEvent, keyMissedKeywordAttr,
  301.                                     typeWildCard, &returnedType, nil, 0,
  302.                                     &actualSize);
  303.     if (err == errAEDescNotFound)    // you got all the required parameters
  304.             return noErr;
  305.     else if (!err)            // you missed a required parameter
  306.             return errAEEventNotHandled;
  307.     else                    // the call to AEGetAttributePtr failed
  308.             return err;
  309. }